package com.yonyou.pmclouds.problemlog.service.rmiimpl;

import java.text.SimpleDateFormat;
import java.util.*;

import com.yonyou.pmclouds.alterandvisa.entity.AlterAndVisaVO;
import com.yonyou.pmclouds.assigninfo.entity.AssignInfoVO;
import com.yonyou.pmclouds.assigninfo.rmiitf.IAssignInfoQuery;
import com.yonyou.pmclouds.basecom.consts.BillTypeConst;
import com.yonyou.pmclouds.basecom.entity.PageObject;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.basecom.util.DateUtils;
import com.yonyou.pmclouds.basecom.util.SqlUtil;
import com.yonyou.pmclouds.businessobject.util.SortListUtil;
import com.yonyou.pmclouds.copyperson.entity.CopyPersonVO;
import com.yonyou.pmclouds.copyperson.rmiitf.ICopyPersonQuery;
import com.yonyou.pmclouds.organization.entity.OrganizationVO;
import com.yonyou.pmclouds.organization.rmiitf.OrganizationQuery;
import com.yonyou.pmclouds.pmpub.entity.QueryListParam;
import com.yonyou.pmclouds.pmpub.rmiitf.IPageQuerySerivce;
import com.yonyou.pmclouds.problemlog.entity.ProblemLogBillStatus;
import com.yonyou.pmclouds.task.rmiitf.TaskRemoteService;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.dubbo.config.annotation.Service;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.picture.rmiitf.PictureRemoteService;
import com.yonyou.pmclouds.problemlog.entity.ProblemLogVO;
import com.yonyou.pmclouds.problemlog.mapper.ProblemLogMapper;
import com.yonyou.pmclouds.problemlog.service.rmiitf.ProblemLogQuery;
import com.yonyou.pmclouds.procedure.entity.ProcedureVO;
import com.yonyou.pmclouds.procedure.rmiitf.ProcedureQuery;
import com.yonyou.pmclouds.project.entity.ProjectVO;
import com.yonyou.pmclouds.project.rmiitf.ProjectSimpleQuery;
import com.yonyou.pmclouds.reason.entity.ProblemReasonRefVO;
import com.yonyou.pmclouds.reason.entity.ProblemReasonVO;
import com.yonyou.pmclouds.reason.rmiitf.ProblemReasonQuery;
import com.yonyou.pmclouds.repairlog.entity.RepairLogVO;
import com.yonyou.pmclouds.repairlog.service.rmiitf.RepairLogService;

@Service(version = ApplicationConsts.APPLICATION_VERSION, interfaceClass = ProblemLogQuery.class, timeout = 4000)
public class ProblemLogQueryImpl implements ProblemLogQuery , IPageQuerySerivce<ProblemLogVO> {

    @Autowired
    private ProjectSimpleQuery projectQuery;
    @Autowired
    private ProcedureQuery processQuery;
    @Autowired
    private ProblemLogMapper mapper;
    @Autowired
    private RepairLogService repairService;
    @Autowired
    private PictureRemoteService picService;
    @Autowired
    private ProblemReasonQuery problemReasonQuery;
    @Autowired
    private OrganizationQuery organizationQuery;
    @Autowired
    private TaskRemoteService taskRemoteService;
    @Autowired
    private IAssignInfoQuery assignInfoQuery;
    @Autowired
    private ICopyPersonQuery copyPersonQuery;

    @Override
    public ProblemLogVO[] qureyByProject(String pk_project) throws BusinessException {
        if (StringUtils.isEmpty(pk_project)) {
            return null;
        }
        ProblemLogVO[] vos = mapper.selectByPkProject(pk_project);
        if(vos == null || vos.length <= 0){
            return null;
        }

        setOverTime(vos);

        getPictures(vos);  //添加照片

        // 查询交办人
        setAssignInfo(vos);

        // 查询抄送人
        setCopyPerson(vos);

        return setProblemReason(vos);
    }

    private void setAssignInfo(ProblemLogVO[] problemLogVOS) throws BusinessException{
        List<String> pkProblemList = new ArrayList<>();
        for(ProblemLogVO logVO : problemLogVOS){
            pkProblemList.add(logVO.getPk_problem());
        }

        List<AssignInfoVO> assignInfoVOS = assignInfoQuery.queryByPkBills(pkProblemList);
        if(assignInfoVOS == null || assignInfoVOS.size() <= 0){
            return;
        }

        Map<String, List<AssignInfoVO>> assignMap = new HashMap<>();
        for(AssignInfoVO assignInfoVO : assignInfoVOS){
            String pkBill = assignInfoVO.getPkBill();
            List<AssignInfoVO> assignVOList = assignMap.get(pkBill);
            if(assignVOList != null){
                assignVOList.add(assignInfoVO);
            }else {
                assignVOList = new ArrayList<>();
                assignVOList.add(assignInfoVO);
                assignMap.put(pkBill, assignVOList);
            }
        }

        for(ProblemLogVO logVO : problemLogVOS){
            List<AssignInfoVO> assignInfoVOList = assignMap.get(logVO.getPk_problem());
            if(assignInfoVOList != null && assignInfoVOList.size() > 0){
                SortListUtil.sort(assignInfoVOList, AssignInfoVO.SORT_FIELD,AssignInfoVO.SORT_WAY);
                logVO.setAssignVOList(assignInfoVOList);
            }
        }

    }

    private void setCopyPerson(ProblemLogVO[] problemLogVOS) throws BusinessException{
        List<String> pkProblemList = new ArrayList<>();
        for(ProblemLogVO logVO : problemLogVOS){
            pkProblemList.add(logVO.getPk_problem());
        }

        List<CopyPersonVO> copyPersonVOS = copyPersonQuery.queryByPkBills(pkProblemList);
        if(copyPersonVOS == null || copyPersonVOS.size() <= 0){
            return;
        }

        Map<String, List<CopyPersonVO>> copyPersonMap = new HashMap<>();
        for(CopyPersonVO copyPersonVO : copyPersonVOS){
            String pkBill = copyPersonVO.getPkBill();
            List<CopyPersonVO> copyPersonVOList = copyPersonMap.get(pkBill);
            if(copyPersonVOList != null){
                copyPersonVOList.add(copyPersonVO);
            }else {
                copyPersonVOList = new ArrayList<>();
                copyPersonVOList.add(copyPersonVO);
                copyPersonMap.put(pkBill, copyPersonVOList);
            }
        }

        for(ProblemLogVO logVO : problemLogVOS){
            List<CopyPersonVO> copyPersonVOList = copyPersonMap.get(logVO.getPk_problem());
            if(copyPersonVOList != null && copyPersonVOList.size() > 0){
                logVO.setCopyPersonVOS(copyPersonVOList);
            }
        }
    }



    @Override
    public String[] queryPics(String pk_problemlog) throws BusinessException {
        return picService.queryPicNamesByPkEntity(pk_problemlog);
    }

    @Override
    public ProblemLogVO queryOne(String pk_problemlog) throws BusinessException {
        ProblemLogVO problemLogVO = mapper.getById(pk_problemlog);
        if(problemLogVO == null){
            return null;
        }

        // 查询表体整改记录信息
        RepairLogVO[] vos = repairService.query(pk_problemlog);
        if(vos != null){
            for(RepairLogVO repairLogVO : vos){
                repairLogVO.setPk_problem(repairLogVO.getPk_problemlog());
            }
            problemLogVO.setRepairlogs(vos);
        }

        // 查询待办获取交办记录
        setAssignInfo(new ProblemLogVO[]{problemLogVO});

        // 查询抄送人
        setCopyPerson(new ProblemLogVO[]{problemLogVO});

        // 处理图片
        String[] pics = queryPics(pk_problemlog);
        problemLogVO.setPictures(pics);
        // 处理参照字段
        return setRefFileds(problemLogVO);
    }

    @Override
    public Integer selectCountByProject(String pkProject) {
        return mapper.selectCountByProject(pkProject);
    }

    @Override
    public boolean queryRefByIds(String code, String[] ids) throws BusinessException {
        boolean flag = false;
        Integer count = mapper.selectRefByCode(code, ids);
        if (count != null && count > 0) {
            flag = true;
        }
        return flag;
    }

    @Override
    public ProblemLogVO[] queryProblemLog(String pk_project, int billStatus) throws BusinessException {
        ProblemLogVO[] vos = mapper.queryProblemLog(pk_project, billStatus);
        sortOverTime(vos);
        return setProblemReason(vos);
    }

    @Override
    public PageObject<Object> queryByCondition(String[] pkProjects, String[] creators, String startDate, String endDate, int[] billStatus, int pageStart, int pageSize) throws BusinessException {

        int count = mapper.countByCondition(pkProjects, creators, startDate, endDate, billStatus);

        ProblemLogVO[] problemLogVOs = mapper.queryByCondition(pkProjects, creators, startDate, endDate, billStatus, pageStart, pageSize);

        return new PageObject<Object>(setRefFileds(problemLogVOs), count, pageStart);
    }

    /**
     * 添加照片
     */
    private void getPictures(ProblemLogVO[] vos) throws BusinessException {
        if (ArrayUtils.isEmpty(vos)) return;
        List<String> pkBills = new ArrayList<>();
        for (ProblemLogVO vo : vos) {
            if (vo != null && vo.getPk_problem() != null) pkBills.add(vo.getPk_problem());
        }
        if (pkBills.size() == 0) return;

        Map<String, List<String>> picMap = picService.queryPicsByPkEntitys(pkBills.toArray(new String[0]));
        if (picMap == null) return;

        for (ProblemLogVO vo : vos) {
            if (vo != null && picMap.get(vo.getPk_problem()) != null)
                vo.setPictures(picMap.get(vo.getPk_problem()).toArray(new String[0]));
        }
    }

    private void setOverTime(ProblemLogVO[] vos) {
        if (ArrayUtils.isNotEmpty(vos)) {
            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.HOUR_OF_DAY, 0);
            cal.set(Calendar.SECOND, 0);
            cal.set(Calendar.MINUTE, 0);
            cal.set(Calendar.MILLISECOND, 0);
            for (ProblemLogVO vo : vos) {
                if (vo.getBillstatus() == ProblemLogBillStatus.STATUS_REPAIRING &&
                        (vo.getEnddate() != null && vo.getEnddate().compareTo(cal.getTime()) < 0)) {
                    vo.setOverTime(true);
                }
            }
        }
    }

    private void sortOverTime(ProblemLogVO[] vos) {
        if (ArrayUtils.isNotEmpty(vos)) {
            List<ProblemLogVO> overtimeVOs = new ArrayList<>();
            List<ProblemLogVO> intimeVOs = new ArrayList<>();
            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.HOUR_OF_DAY, 0);
            cal.set(Calendar.SECOND, 0);
            cal.set(Calendar.MINUTE, 0);
            cal.set(Calendar.MILLISECOND, 0);
            for (ProblemLogVO vo : vos) {
                if (vo.getBillstatus() == ProblemLogBillStatus.STATUS_REPAIRING &&
                        (vo.getEnddate() != null && vo.getEnddate().compareTo(cal.getTime()) < 0)) {
                    vo.setOverTime(true);
                    overtimeVOs.add(vo);
                } else {
                    intimeVOs.add(vo);
                }
            }
            for (ProblemLogVO vo : intimeVOs) {
                overtimeVOs.add(vo);
            }
            for (int i = 0; i < vos.length; i++) {
                vos[i] = overtimeVOs.get(i);
            }
        }
    }

    private ProblemLogVO[] setProblemReason(ProblemLogVO[] vos) throws BusinessException {
        if (ArrayUtils.isEmpty(vos)) {
            return null;
        }
        HashSet<String> pks = new HashSet<String>();
        for (ProblemLogVO problemLogVO : vos) {
            pks.add(problemLogVO.getPk_problemreason());
        }
        Map<String, ProblemReasonRefVO> reasonMap = problemReasonQuery.queryRefs(pks.toArray(new String[pks.size()]));
        for (ProblemLogVO problemLogVO : vos) {
            ProblemReasonRefVO problemReasonRefVO = reasonMap.get(problemLogVO.getPk_problemreason());
            problemLogVO.setProblemreason_name(problemReasonRefVO.getSname());
        }
        return vos;
    }

    private ProblemLogVO setRefFileds(ProblemLogVO vo) throws BusinessException {
        // 问题原因
        ProblemReasonVO problemReasonVO = problemReasonQuery.getById(vo.getPk_problemreason());
        vo.setProblemreason_name(problemReasonVO.getSname());
        // 工序
        String pk_process = vo.getPk_process();
        if (!StringUtils.isEmpty(pk_process)) {
            ProcedureVO procedureVO = processQuery.getById(pk_process);
            vo.setProcess_name(procedureVO.getSname());
        }
        // 项目
        ProjectVO projectVO = projectQuery.queryProject(vo.getPk_project());
        vo.setProject_code(projectVO.getScode());
        vo.setProject_name(projectVO.getSname());
        String pkOrg = projectVO.getPkOrg();
        if (StringUtils.isNotEmpty(pkOrg)) {
            OrganizationVO organizationVO = organizationQuery.queryByPkSrc(RuntimeEnvironment.getTenantId(), pkOrg);
            vo.setOrgName(organizationVO == null ? null : organizationVO.getSname());
        }

        return vo;
    }

    private ProblemLogVO[] setRefFileds(ProblemLogVO[] vos) throws BusinessException {
        if (ArrayUtils.isEmpty(vos)) {
            return new ProblemLogVO[0];
        }

        Set<String> reasonSet = new HashSet<String>();
        Set<String> projectSet = new HashSet<String>();
        Set<String> pkSet = new HashSet<String>();
        Set<String> proceSet = new HashSet<String>();

        for (ProblemLogVO vo :
                vos) {
            reasonSet.add(vo.getPk_problemreason());
            projectSet.add(vo.getPk_project());
            pkSet.add(vo.getPk_problem());
            proceSet.add(vo.getPk_process());
        }

        Map<String, ProjectVO> projectVOMap = projectQuery.queryProjects(projectSet.toArray(new String[0]));
        Map<String, ProblemReasonRefVO> reasonVOMap = problemReasonQuery.queryRefs(reasonSet.toArray(new String[0]));
        Map<String, List<String>> pictureVOMap = picService.queryPicsByPkEntitys(pkSet.toArray(new String[0]));
        Map<String, String> procedureNameMap = processQuery.queryNameByIds(proceSet.toArray(new String[0]));

        for (ProblemLogVO vo :
                vos) {
            vo.setProject_name(projectVOMap.get(vo.getPk_project()) == null ? null : projectVOMap.get(vo.getPk_project()).getSname());
            vo.setProject_code(projectVOMap.get(vo.getPk_project()) == null ? null : projectVOMap.get(vo.getPk_project()).getScode());
            vo.setProblemreason_name(reasonVOMap.get(vo.getPk_problemreason()) == null ? null : reasonVOMap.get(vo.getPk_problemreason()).getSname());
            vo.setPicNum(pictureVOMap.get(vo.getPk_problem()) == null ? 0 : pictureVOMap.get(vo.getPk_problem()).size());
            vo.setProcess_name(procedureNameMap.get(vo.getPk_process()));
        }

        return vos;
    }

    @Override
    public int countByProject(QueryListParam param) throws BusinessException{

        int count = mapper.countByCondition( new String[]{param.getPkProject()}, null, param.getStartDate(), param.getEndDate(), null);

        return count;
    }

    @Override
    public ProblemLogVO[] queryByProject(QueryListParam param) throws BusinessException {

        ProblemLogVO[] vos = mapper.queryByCondition(new String[]{param.getPkProject()}, null,  param.getStartDate(), param.getEndDate(), null,param.getPageStart(),param.getPageSize());

        setOverTime(vos);

        getPictures(vos);

        setProblemReason(vos);
        return vos;
    }


    @Override
    public String getBillType() {
        return BillTypeConst.PROBLEMLOG_BILLTYPE;
    }
}
